<?php

namespace App\Http\Controllers\Backstage\System;

use Validator;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Validation\Rule;
use App\Services\RouteService;
use App\Route;

class RouteController extends Controller
{
    private $routeService = null;

    public function __construct(RouteService $routeService)
    {
        $this->routeService = $routeService;
    }

    public function index()
    {
        return view('backstage.system.route.route');
    }

    public function create()
    {
        return view('backstage.system.route.create');
    }

    public function getRoutes(Request $request)
    {
        return $this->routeService
            ->getRoutes($request->all());
    }

    public function saveNew(Request $request)
    {
        $input = $request->all();

        $this->validateWhenSaveNew($input);

        Route::create($input);

        return response()->json([
            'Success' => true,
            'Message' => '新增路由成功',
        ]);
    }

    public function edit($routeId)
    {
        $route = Route::findOrFail($routeId);
        return view('backstage.system.route.create', [
            'route' => $route
        ]);
    }

    public function update(Request $request)
    {
        $input = $request->all();

        $this->validateWhenSaveUpdate($input);

        $route = Route::findOrFail($input['id']);
        $route->update($input);

        return response()->json([
            'Success' => true,
            'Message' => '保存修改路由成功',
        ]);
    }

    public function delete(Request $request)
    {
        $input = $request->all();

        $this->validateWhenDelete($input);

        $route = Route::findOrFail($input['id']);
        $route->delete();

        return response()->json([
            'Success' => true,
            'Message' => '删除路由成功',
        ]);
    }


    private function validateWhenSaveNew(Array $input)
    {
        return Validator::make($input, [
            //基础性验证
            'name' => 'required|max:50|unique:routes,name',
            'code' => 'required|max:100|unique:routes,code',
            'method' => [
                'required',
                Rule::in(Route::getRouteMethodKeys())
            ],
            'route' => [
                'required',
                'max:200',
                Rule::unique('routes')->where(function ($query) use($input) {
                    $query->where('route', $input['route'])->where('method', $input['method']);
                })
            ],
            'action' => 'required|max:200',
            'slug' => [
                'max:200',
                Rule::unique('routes')->where(function ($query) use($input) {
                    $query->whereNotNull('slug')->where('slug', '<>', '')->where('slug', $input['slug']);
                })
            ],
            'route_type' => [
                'required',
                Rule::in(Route::getRouteTypeKeys())
            ],
            'sort_order' => 'required|numeric'
        ], $this->getValidateMessagesWhenSaveNew())->after(function ($validator) use($input) {
            //附加逻辑性验证，只有当基础验证规则完全无法实现时才可以自定义逻辑验证
            //这里留白只是为了定义规范，实际开发中如果没有对应的判断逻辑，则需要追加错误
            // if ($this->isSomethingElseWrong())
            //    $validator->errors()->add('newfield', '又有一个新的验证未通过');
        })->validate();
    }

    private function getValidateMessagesWhenSaveNew()
    {
        return [
            'name.required' => '路由名称必须存在',
            'name.max'  => '路由名称长度不可超过:max',
            'name.unique' => '已经存在该路由名称',
            'code.required' => '路由代码必须填写',
            'code.max'  => '路由代码长度不可超过:max',
            'code.unique' => '已经存在该路由代码',
            'method.required' => '路由方法必须填写',
            'method.in' => '路由方法输入值不正确',
            'route.required' => '路由路径必须填写',
            'route.max' => '路由路径长度不可以超过:max',
            'route.unique' => '路由路径和路由方法的组合不可重复',
            'action.required' => '路由Action必须填写',
            'action.max' => '路由Action长度不可以超过:max',
            'slug.max' => '路由别名长度不可以超过:max',
            'slug.unique' => '路由别名不为空时不可以重复',
            'route_type.required' => '路由类型必须存在',
            'route_type.in' => '路由类型的输入值不正确',
            'sort_order.required' => '排序号必须存在',
            'sort_order.numeric' => '排序号必须是数字',
        ];
    }

    private function validateWhenSaveUpdate(Array $input)
    {
        return Validator::make($input, [
            //基础性验证
            'id' => 'required|exists:routes,id',
            'name' => [
                'required',
                'max:50',
                Rule::unique('routes')->where(function ($query) use($input) {
                    $query->where('name', $input['name'])
                        ->where('id', '<>', $input['id']);
                })
            ],
            'code' => [
                'required',
                'max:100',
                Rule::unique('routes')->where(function ($query) use($input) {
                    $query->where('code', $input['code'])
                        ->where('id', '<>', $input['id']);
                })
            ],
            'method' => [
                'required',
                Rule::in(Route::getRouteMethodKeys())
            ],
            'route' => [
                'required',
                'max:200',
                Rule::unique('routes')->where(function ($query) use($input) {
                    $query->where('route', $input['route'])
                        ->where('method', $input['method'])
                        ->where('id', '<>', $input['id']);
                })
            ],
            'action' => 'required|max:200',
            'slug' => [
                'max:200',
                Rule::unique('routes')->where(function ($query) use($input) {
                    $query->whereNotNull('slug')
                        ->where('slug', '<>', '')
                        ->where('slug', $input['slug'])
                        ->where('id', '<>', $input['id']);
                })
            ],
            'route_type' => [
                'required',
                Rule::in(Route::getRouteTypeKeys())
            ],
            'sort_order' => 'required|numeric'
        ], $this->getValidateMessagesWhenSaveUpdate())->validate();
    }

    private function getValidateMessagesWhenSaveUpdate()
    {
        return [
            'id.required' => '必须传入路由ID',
            'id.exists' => '该路由ID参数有误，路由不存在',
            'name.required' => '路由名称必须存在',
            'name.max'  => '路由名称长度不可超过:max',
            'name.unique' => '已经存在同样路由名称的其它记录',
            'code.required' => '路由代码必须填写',
            'code.max'  => '路由代码长度不可超过:max',
            'code.unique' => '已经存在同样路由代码的其它记录',
            'method.required' => '路由方法必须填写',
            'method.in' => '路由方法输入值不正确',
            'route.required' => '路由路径必须填写',
            'route.max' => '路由路径长度不可以超过:max',
            'route.unique' => '已经存在其它同样的路由路径及路由方法组合',
            'action.required' => '路由Action必须填写',
            'action.max' => '路由Action长度不可以超过:max',
            'slug.max' => '路由别名长度不可以超过:max',
            'slug.unique' => '路由别名不为空时不可以重复',
            'route_type.required' => '路由类型必须存在',
            'route_type.in' => '路由类型的输入值不正确',
            'sort_order.required' => '排序号必须存在',
            'sort_order.numeric' => '排序号必须是数字',
        ];
    }

    private function validateWhenDelete(Array $input)
    {
        return Validator::make($input, [
                'id' => 'required|exists:routes,id'
            ], [
                'id.required' => '必须传入路由ID',
                'id.exists' => '该路由ID参数有误，路由不存在'
            ])->after(function ($validator) use($input) {
                //验证外键约束，不是必须的，需要根据业务场景来判断
                //在有一些业务场景下，需要进行级联删除而不是判断约束
                if ($this->routeService->hasConstrait($input['id'])) {
                    $validator->errors()->add('id', '该路由已经被分配了权限，不可删除');
                }
            })->validate();
    }
}
